﻿using System;
using System.Collections.Generic;
using System.Text;
using Model;
using System.Data;
using Common.Logging;
using Utility;
using AppToolKit.Core.Context.Spring;

using IBLL;
using BLL.Action.Core.Caching;

namespace BLL.Business.ActionBusiness
{
    public class ActionBusiness:IActionBusiness,IAutoWiring
    {
        [AutoWiring]
        public ActionBusinessDao Dao { get; set; }
        [AutoWiring]
        public ClientCache Cache { get; set; }

        //ILog log = LogManager.GetLogger(LogDefault.AppInfo);
        //ILog logError = LogManager.GetLogger(LogDefault.AppError);
        /// <summary>
        /// 插入或更新数据
        /// </summary>
        /// <param name="ds"></param>
        /// <param name="PrimaryKey"></param>
        /// <param name="tableName"></param>
        /// <param name="isUpdate"></param>
        /// <returns></returns>
        public bool Save(DataSet ds, string[] PrimaryKey, string tableName, bool isUpdate)
        {

            LogHelper.GetInfoLog().Debug("save");


            string sqlPrimaryKey = string.Empty;
            string sqlEnd = string.Empty;

            List<ColumnDefine> Columnlist = CacheHelper.Cache(Cache, string.Format("{0}_{1}", "COL", tableName), delegate { return GetColMapping(ds); }) as List<ColumnDefine>;
            string Sql = string.Empty;
            foreach (DataRow datarow in ds.Tables[0].Rows)
            {
                bool Success = false;
                try
                {
                   Success= Save(PrimaryKey, tableName, isUpdate, Columnlist, datarow);
                     
                }
                catch (Exception ex)
                {
                    Success = false;
                    LogHelper.GetErrorLog().Debug(ex);
                }
                finally
                {
                    CallBack(Success);
                }
            }
            return false;

        }

        private void CallBack(bool Success)
        {
            
        }
        private bool Save(string[] PrimaryKey, string tableName, bool isUpdate, List<ColumnDefine> Columnlist, DataRow datarow)
        {
            if (DataIsExist(datarow, PrimaryKey, tableName, Columnlist))
            {
                if (isUpdate)
                    Update(PrimaryKey, Columnlist, datarow, tableName);

            }
            else
            {
                Insert(Columnlist, datarow, tableName);
            }
            return true;
        }
        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="PrimaryKey">主键列</param>
        /// <param name="Columnlist">数据列名</param>
        /// <param name="datarow">数据</param>
        /// <param name="tableName">表名</param>
        private void Update(string[] PrimaryKey, List<ColumnDefine> Columnlist, DataRow datarow, string tableName)
        {
            string sql = string.Empty;
            string sqlPrimaryKey = string.Empty;
            string sqlEnd = string.Empty;
            foreach (ColumnDefine ColDefine in Columnlist)
            {
                sql += string.Format("{0}={1},", ColDefine.Column, SafeGetData(ColDefine.DbType, datarow[ColDefine.Column]));
            }
            foreach (string strPrimaryKey in PrimaryKey)
            {
                sqlPrimaryKey += string.Format("{0}={1} and ", strPrimaryKey, SafeGetData(Find(strPrimaryKey, Columnlist).DbType, datarow[strPrimaryKey]));
            }
            sqlPrimaryKey = StringHelper.StrEndSubstring(sqlPrimaryKey, "and");

            sql = StringHelper.StrEndSubstring(sql, ",");

            
                      
            Dao.Update(sql, sqlPrimaryKey, tableName);
         
        }
        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="Columnlist">列定义</param>
        /// <param name="datarow">列数据</param>
        /// <param name="tableName">表名</param>
        private void Insert(List<ColumnDefine> Columnlist, DataRow datarow, string tableName)
        {
            string strSqlName = string.Empty;
            string strSqlValue = string.Empty;
            foreach (ColumnDefine strName in Columnlist)
            {
                strSqlName += string.Format("{0},", strName.Column);
                strSqlValue += string.Format("{0},", SafeGetData(strName.DbType, datarow[strName.Column]));
            }
            strSqlName = StringHelper.StrEndSubstring(strSqlName, ",");
            strSqlValue = StringHelper.StrEndSubstring(strSqlValue, ",");
             
           
            Dao.Insert(tableName, strSqlName, strSqlValue);

        }
        public bool DataIsExist(DataRow dr, string[] PrimaryKey, string tableName, List<ColumnDefine> Columnlist)
        {
            string data = string.Empty;
            data = GetWhereCondition(dr, PrimaryKey, Columnlist);
            string sql = string.Format("select count(*) from {1} where {0}", data, tableName);
            LogHelper.GetInfoLog().Debug(string.Format("查询 Sql:{0}", sql));
            object o = Dao.Exist(sql);
            if ((int)o >= 1)
                return true;
            else
                return false;
        }

        private string GetWhereCondition(DataRow dr, string[] PrimaryKey, List<ColumnDefine> Columnlist)
        {
            string data = string.Empty;
            foreach (string key in PrimaryKey)
            {
                data += string.Format("{0}={1} and ", key, SafeGetData(Find(key, Columnlist).DbType, dr[key]));
            }
            
            return StringHelper.StrEndSubstring(data,"and");
        }
        /// <summary>
        /// 处理数据
        /// </summary>
        /// <param name="dbType"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private string SafeGetData(Type dbType, object data)
        {
            string result = string.Empty;
            if (Convert.IsDBNull(data))
            {
                result = "NULL";

            }
            else
            {
                if (dbType == typeof(string) || dbType == typeof(DateTime))
                {
                    result = string.Format("'{0}'", StringEncodingConvert(data.ToString().TrimEnd(' ').Replace("'", "''"), Encoding.Default, Encoding.UTF8));
                }
                else
                    result = data.ToString();
            }
            return result;

        }
        /// <summary>
        /// 数据转换
        /// </summary>
        /// <param name="srcString"></param>
        /// <param name="srcEnoding"></param>
        /// <param name="desEncoding"></param>
        /// <returns></returns>
        private static string StringEncodingConvert(string srcString, Encoding srcEnoding, Encoding desEncoding)
        {
            //   Convert   the   string   into   a   byte[].   
            byte[] srcBytes = srcEnoding.GetBytes(srcString.Replace('\0',Convert.ToChar(32)));

            //   Perform   the   conversion   from   one   encoding   to   the   other.   
            byte[] desBytes = Encoding.Convert(srcEnoding, desEncoding, srcBytes);

            //   Convert   the   new   byte[]   into   a   char[]   and   then   into   a   string.   
            //   This   is   a   slightly   different   approach   to   converting   to   illustrate   
            //   the   use   of   GetCharCount/GetChars.   
            char[] desChars = new char[desEncoding.GetCharCount(desBytes, 0, desBytes.Length)];
            desEncoding.GetChars(desBytes, 0, desBytes.Length, desChars, 0);
            string desString = new string(desChars);

            //   Display   the   strings   created   before   and   after   the   conversion.   
            return desString;
        }
        /// <summary>
        /// 从dataset中 获取列名
        /// </summary>
        /// <param name="ds">数据源</param>
        /// <returns></returns>
        private List<ColumnDefine> GetColMapping(DataSet ds)
        {
            List<ColumnDefine> Columnlist = new List<ColumnDefine>();
            foreach (DataColumn datacol in ds.Tables[0].Columns)
            {
                ColumnDefine define = new ColumnDefine();
                define.Column = datacol.ColumnName;
                define.DbType = datacol.DataType;
                Columnlist.Add(define);
            }
            return Columnlist;
        }
        /// <summary>
        /// 根据列名 获取列类型
        /// </summary>
        /// <param name="Column"></param>
        /// <param name="Columnlist"></param>
        /// <returns></returns>
        public ColumnDefine Find(string Column, List<ColumnDefine> Columnlist)
        {
            foreach (ColumnDefine mapping in Columnlist)
            {
                if (mapping.Column == Column)
                    return mapping;
            }
            throw new ApplicationException("无法找到对应列");
        }
    }
}
